import java.net.*;
import java.io.*;
import java.util.*;

public class UserInterface{
	Boolean serverRunning = false;
	ArrayList<Command> commands = new ArrayList<Command>();
	ArrayList<String> commandStrings = new ArrayList<String>();
	public int port;
	Scanner scanner = new Scanner(System.in);
	ServerStatus serverStatus = new ServerStatus();

	public UserInterface(int portnumber){
		this.port = portnumber;
		appendOption("Start Server", new ToggleServer());
		appendOption("Exit", new Exit());
		showMenu();
	}

	/* This clears the screen, when the program is first launched,
	 * it works on linux, but should be checked still on windows and
	 * osx
	 */
	private void clearScreen(){
		final String ANSI_CLS = "\u001b[2J";
		final String ANSI_HOME = "\u001b[H";
		System.out.print(ANSI_CLS + ANSI_HOME);
		System.out.flush();
	}

	public void showMenu(){
		while(true){
			clearScreen();
			System.out.println("Server Status: " + getServerStatus());
			for(int i = 0; i<commands.size(); i++){
				System.out.println(commandStrings.get(i));
			}
			System.out.println("Enter Choice:");

			try{
				Thread.sleep(1000);
			} catch(java.lang.InterruptedException e){
				System.out.println(e);
			}
			try{
				if(scanner.hasNext()){
					int index = scanner.nextInt() - 1;
					commands.get(index).execute();
				} else {
					Thread.sleep(1500);
					clearScreen();
				}
			} catch(Exception q){
				clearScreen();
				System.out.println("This doesn't work");
			}
		}
	}

	private String getServerStatus(){
		if(serverRunning == true){
			return "Running on port "+ port;
		} else {
			return "Stopped";
		}
	}

	public void appendOption(String name, Command command){
		// This will initialize the command with an id that references
		// the place in the menu that it will fulfill, not the index of
		// the arrayList.
		command.init(commands.size() + 1, this);

		this.commands.add(command);
		this.commandStrings.add(commands.size() + ": " + name);	
	}

	public void removeOption(int index){
		commands.remove(index);
		commandStrings.remove(index);
	}
}

// class that executes the server class
class ToggleServer implements Command{
	int id;
	UserInterface parent;
	ServerStatus serverStatus;
	Thread serverThread;

	public void init(int id, UserInterface parent){
		System.out.println("ToggleServer Loaded");
		this.id = id;
		this.parent = parent;
		this.serverStatus = parent.serverStatus;
		serverThread = new Thread(new Server(parent.port, serverStatus));
		serverThread.start();
	}

	public void execute(){
		if(serverStatus.running){
			// shut down server
			serverStatus.running = false;
			parent.serverRunning = false;
			parent.commandStrings.set(id - 1, id + ": " + "Start Server");
		} else {
			// start server
			serverStatus.running = true;
			parent.serverRunning = true;
			parent.commandStrings.set(id - 1, id + ": " + "Stop Server");
		}
	}
}

//exits the program
class Exit implements Command{
	public void init(int id, UserInterface parent){

	}

	public void execute(){
		System.exit(0);
	}
}
